package sk.naive.talker.adapter;

import java.util.*;

/**
 * MessageProcessingContext stores state of message processing.
 * Resulting message is constructed in message consumer object which can be
 * replaced by another one. By default BufferMessageConsumer object is used.
 *
 * @author <a href="mailto:virgo@naive.deepblue.sk">Richard "Virgo" Richter</a>
 * @version $Revision: 1.4 $ $Date: 2005/01/06 16:27:05 $
 */
public class MessageProcessingContext {
	private MessageConsumer consumer;
	private AbstractUser user;
	private Map props;
	private boolean interruptProcessing;

	public MessageProcessingContext(AbstractUser user) {
		this.user = user;
		consumer = new BufferMessageConsumer();
		props = new HashMap();
	}

	public void append(String s) throws TagProcessorException {
		consumer.append(s);
	}

	public void switchConsumer(MessageConsumer newConsumer, boolean appendOld) throws TagProcessorException {
		if (appendOld) {
			newConsumer.append(consumer.result());
		}
		consumer = newConsumer;
	}

	public void interruptProcessing() {
		interruptProcessing = true;
	}

	public boolean isProcessingInterrupted() {
		return interruptProcessing;
	}

	public MessageConsumer getConsumer() {
		return consumer;
	}

	public AbstractUser getUser() {
		return user;
	}

	public String result() {
		return consumer.result();
	}

	public Object get(String key) {
		return props.get(key);
	}

	public void set(String key, Object val) {
		props.put(key, val);
	}

	public void unset(String key) {
		props.remove(key);
	}

	/**
	 * MessageConsumer is responsible for accepting parts of the resulting
	 * message. When result method is called consumer should provide constructed
	 * message. This can occure when the whole message is processed or when
	 * consumer is switched to another one.
	 */
	public interface MessageConsumer {
		public void append(String s) throws TagProcessorException;
		public String result();
	}

	/**
	 * Default implementation of the message consumer is just the wrapper
	 * around the StringBuffer.
	 */
	public static class BufferMessageConsumer implements MessageConsumer {
		protected StringBuilder buffer = new StringBuilder();
		public void append(String s) throws TagProcessorException {
			buffer.append(s);
		}
		public String result() {
			return buffer.toString();
		}
	}
}
